package com.sky.skyopsserver.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sky.skyopsserver.aspect.ApiOperationLog;
import com.sky.skyopsserver.service.EnvironmentService;
import com.sky.skyopsserver.utils.PageResponse;
import com.sky.skyopsserver.utils.Response;
import com.sky.skyopsserver.vos.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 环境信息控制器
 * @author Administrator
 * @since 2025-01-17
 */
@Slf4j
@RestController
@RequestMapping("/api/environment")
@RequiredArgsConstructor
@Validated
@Tag(name = "环境管理", description = "环境信息的增删改查操作")
public class EnvironmentController {

    private final EnvironmentService environmentService;

    /**
     * 添加环境
     * 
     * @param reqVO 添加环境请求VO
     * @return 环境ID
     */
    @PostMapping("/add")
    @Operation(summary = "添加环境", description = "新增一个环境信息")
    @ApiOperationLog(description = "添加环境")
    public Response<Long> addEnvironment(@Valid @RequestBody EnvironmentAddReqVO reqVO) {
        Long environmentId = environmentService.addEnvironment(reqVO);
        return Response.success(environmentId);
    }

    /**
     * 更新环境信息
     * 
     * @param reqVO 更新环境请求VO
     * @return 操作结果
     */
    @PutMapping("/update")
    @Operation(summary = "更新环境信息", description = "修改环境的基本信息")
    @ApiOperationLog(description = "更新环境信息")
    public Response<Boolean> updateEnvironment(@Valid @RequestBody EnvironmentUpdateReqVO reqVO) {
        Boolean result = environmentService.updateEnvironment(reqVO);
        return Response.success(result);
    }

    /**
     * 删除环境
     * 
     * @param id 环境ID
     * @return 操作结果
     */
    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除环境", description = "根据ID删除指定环境")
    @ApiOperationLog(description = "删除环境")
    public Response<Boolean> deleteEnvironment(
            @Parameter(description = "环境ID", required = true)
            @PathVariable("id") @NotNull(message = "环境ID不能为空") @Positive(message = "环境ID必须为正数") Long id) {
        Boolean result = environmentService.deleteEnvironment(id);
        return Response.success(result);
    }

    /**
     * 批量删除环境
     * 
     * @param ids 环境ID列表
     * @return 操作结果
     */
    @DeleteMapping("/batch-delete")
    @Operation(summary = "批量删除环境", description = "根据ID列表批量删除环境")
    @ApiOperationLog(description = "批量删除环境")
    public Response<Boolean> batchDeleteEnvironment(
            @Parameter(description = "环境ID列表", required = true)
            @RequestBody @NotEmpty(message = "环境ID列表不能为空") List<@Positive(message = "环境ID必须为正数") Long> ids) {
        Boolean result = environmentService.batchDeleteEnvironment(ids);
        return Response.success(result);
    }

    /**
     * 根据ID查询环境详情
     * 
     * @param id 环境ID
     * @return 环境详情
     */
    @GetMapping("/detail/{id}")
    @Operation(summary = "查询环境详情", description = "根据ID获取环境的详细信息")
    @ApiOperationLog(description = "查询环境详情")
    public Response<EnvironmentRspVO> getEnvironmentById(
            @Parameter(description = "环境ID", required = true)
            @PathVariable("id") @NotNull(message = "环境ID不能为空") @Positive(message = "环境ID必须为正数") Long id) {
        EnvironmentRspVO result = environmentService.getEnvironmentById(id);
        return Response.success(result);
    }

    /**
     * 根据编码查询环境
     * 
     * @param code 环境编码
     * @return 环境信息
     */
    @GetMapping("/detail/code/{code}")
    @Operation(summary = "根据编码查询环境", description = "根据环境编码获取环境信息")
    @ApiOperationLog(description = "根据编码查询环境")
    public Response<EnvironmentRspVO> getEnvironmentByCode(
            @Parameter(description = "环境编码", required = true)
            @PathVariable("code") @NotBlank(message = "环境编码不能为空") String code) {
        EnvironmentRspVO result = environmentService.getEnvironmentByCode(code);
        return Response.success(result);
    }

    /**
     * 分页查询环境列表
     * 
     * @param reqVO 分页查询请求VO
     * @return 分页结果
     */
    @PostMapping("/page")
    @Operation(summary = "分页查询环境列表", description = "根据条件分页查询环境信息")
    @ApiOperationLog(description = "分页查询环境列表")
    public PageResponse<EnvironmentRspVO> getEnvironmentPage(@Valid @RequestBody EnvironmentPageReqVO reqVO) {
        IPage<EnvironmentRspVO> page = environmentService.getEnvironmentPage(reqVO);
        return PageResponse.success(page, page.getRecords());
    }

    /**
     * 查询所有环境选项（用于下拉选择）
     * 
     * @return 环境选项列表
     */
    @GetMapping("/options")
    @Operation(summary = "查询环境选项", description = "获取所有环境的选项列表，用于下拉选择")
    @ApiOperationLog(description = "查询环境选项")
    public Response<List<EnvironmentOptionRspVO>> getAllEnvironmentOptions() {
        List<EnvironmentOptionRspVO> result = environmentService.getAllEnvironmentOptions();
        return Response.success(result);
    }

    /**
     * 查询有应用的环境选项
     * 
     * @return 环境选项列表
     */
    @GetMapping("/options/with-apps")
    @Operation(summary = "查询有应用的环境选项", description = "获取包含应用的环境选项列表")
    @ApiOperationLog(description = "查询有应用的环境选项")
    public Response<List<EnvironmentOptionRspVO>> getEnvironmentOptionsWithApps() {
        List<EnvironmentOptionRspVO> result = environmentService.getEnvironmentOptionsWithApps();
        return Response.success(result);
    }

    /**
     * 查询空环境选项
     * 
     * @return 环境选项列表
     */
    @GetMapping("/options/empty")
    @Operation(summary = "查询空环境选项", description = "获取不包含应用的环境选项列表")
    @ApiOperationLog(description = "查询空环境选项")
    public Response<List<EnvironmentOptionRspVO>> getEmptyEnvironmentOptions() {
        List<EnvironmentOptionRspVO> result = environmentService.getEmptyEnvironmentOptions();
        return Response.success(result);
    }

    /**
     * 获取环境统计信息
     * 
     * @return 环境统计信息
     */
    @GetMapping("/statistics")
    @Operation(summary = "获取环境统计信息", description = "获取环境的各项统计数据")
    @ApiOperationLog(description = "获取环境统计信息")
    public Response<EnvironmentStatisticsRspVO> getEnvironmentStatistics() {
        EnvironmentStatisticsRspVO result = environmentService.getEnvironmentStatistics();
        return Response.success(result);
    }

    /**
     * 检查环境编码是否已存在
     * 
     * @param code 环境编码
     * @param excludeId 排除的环境ID（可选）
     * @return 是否存在
     */
    @GetMapping("/check-code")
    @Operation(summary = "检查环境编码", description = "检查环境编码是否已存在")
    @ApiOperationLog(description = "检查环境编码")
    public Response<Boolean> checkEnvironmentCodeExists(
            @Parameter(description = "环境编码", required = true)
            @RequestParam("code") @NotBlank(message = "环境编码不能为空") String code,
            @Parameter(description = "排除的环境ID")
            @RequestParam(value = "excludeId", required = false) Long excludeId) {
        Boolean result = environmentService.checkEnvironmentCodeExists(code, excludeId);
        return Response.success(result);
    }

    /**
     * 检查环境名称是否已存在
     * 
     * @param name 环境名称
     * @param excludeId 排除的环境ID（可选）
     * @return 是否存在
     */
    @GetMapping("/check-name")
    @Operation(summary = "检查环境名称", description = "检查环境名称是否已存在")
    @ApiOperationLog(description = "检查环境名称")
    public Response<Boolean> checkEnvironmentNameExists(
            @Parameter(description = "环境名称", required = true)
            @RequestParam("name") @NotBlank(message = "环境名称不能为空") String name,
            @Parameter(description = "排除的环境ID")
            @RequestParam(value = "excludeId", required = false) Long excludeId) {
        Boolean result = environmentService.checkEnvironmentNameExists(name, excludeId);
        return Response.success(result);
    }

    /**
     * 根据名称模糊查询环境
     * 
     * @param name 环境名称关键字
     * @return 环境列表
     */
    @GetMapping("/search/name")
    @Operation(summary = "按名称搜索环境", description = "根据环境名称关键字模糊查询环境")
    @ApiOperationLog(description = "按名称搜索环境")
    public Response<List<EnvironmentRspVO>> searchEnvironmentByName(
            @Parameter(description = "环境名称关键字", required = true)
            @RequestParam("name") @NotBlank(message = "环境名称关键字不能为空") String name) {
        List<EnvironmentRspVO> result = environmentService.searchEnvironmentByName(name);
        return Response.success(result);
    }

    /**
     * 根据编码模糊查询环境
     * 
     * @param code 环境编码关键字
     * @return 环境列表
     */
    @GetMapping("/search/code")
    @Operation(summary = "按编码搜索环境", description = "根据环境编码关键字模糊查询环境")
    @ApiOperationLog(description = "按编码搜索环境")
    public Response<List<EnvironmentRspVO>> searchEnvironmentByCode(
            @Parameter(description = "环境编码关键字", required = true)
            @RequestParam("code") @NotBlank(message = "环境编码关键字不能为空") String code) {
        List<EnvironmentRspVO> result = environmentService.searchEnvironmentByCode(code);
        return Response.success(result);
    }

    /**
     * 验证环境编码格式
     * 
     * @param code 环境编码
     * @return 是否有效
     */
    @GetMapping("/validate-code")
    @Operation(summary = "验证环境编码格式", description = "验证环境编码是否符合格式要求")
    @ApiOperationLog(description = "验证环境编码格式")
    public Response<Boolean> validateEnvironmentCode(
            @Parameter(description = "环境编码", required = true)
            @RequestParam("code") @NotBlank(message = "环境编码不能为空") String code) {
        Boolean result = environmentService.validateEnvironmentCode(code);
        return Response.success(result);
    }

    /**
     * 获取所有环境编码列表
     * 
     * @return 环境编码列表
     */
    @GetMapping("/codes")
    @Operation(summary = "获取环境编码列表", description = "获取所有环境的编码列表")
    @ApiOperationLog(description = "获取环境编码列表")
    public Response<List<String>> getAllEnvironmentCodes() {
        List<String> result = environmentService.getAllEnvironmentCodes();
        return Response.success(result);
    }

    /**
     * 获取所有环境名称列表
     * 
     * @return 环境名称列表
     */
    @GetMapping("/names")
    @Operation(summary = "获取环境名称列表", description = "获取所有环境的名称列表")
    @ApiOperationLog(description = "获取环境名称列表")
    public Response<List<String>> getAllEnvironmentNames() {
        List<String> result = environmentService.getAllEnvironmentNames();
        return Response.success(result);
    }

    /**
     * 获取环境下的应用数量
     * 
     * @param environmentId 环境ID
     * @return 应用数量
     */
    @GetMapping("/app-count/{environmentId}")
    @Operation(summary = "获取环境应用数量", description = "获取指定环境下的应用数量")
    @ApiOperationLog(description = "获取环境应用数量")
    public Response<Long> getApplicationCountByEnvironmentId(
            @Parameter(description = "环境ID", required = true)
            @PathVariable("environmentId") @NotNull(message = "环境ID不能为空") @Positive(message = "环境ID必须为正数") Long environmentId) {
        Long result = environmentService.getApplicationCountByEnvironmentId(environmentId);
        return Response.success(result);
    }
}